import React from "react";
import { useState } from "react";
import {
  Layout,
  Row,
  Col,
  Space,
  Button,
  Table,
  Popconfirm,
  Descriptions,
  Divider,
  Input,
  notification,
  Modal,
} from "antd";
import {
  FileAddOutlined,
  FolderOpenOutlined,
  SaveOutlined,
  PlusOutlined,
  DeleteOutlined,
} from "@ant-design/icons";
import { ArgsProps } from "antd/es/notification/interface";
import type { ColumnsType } from "antd/es/table";
import "./App.scss";
import Banner from "./component/banner";
import logo from "./logo.svg";
import { sign } from "crypto";

const { Header, Sider, Content, Footer } = Layout;

interface SignalItem {
  name: string;
  start: number;
  length: number;
  signed: boolean;
  factor: number;
  offset: number;
}

interface Signal {
  key: React.Key;
  name?: string;
  length?: number;
  comment?: string;
  items?: SignalItem[];
}

const App = (): JSX.Element => {
  const [listSignals, setListSignals] = useState<Signal[]>([]);
  const [newRowKey, setNewRowKey] = useState<string>("");
  const [selRowKey, setSelRowKey] = useState<React.Key>();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editSignal, setEditSignal] = useState<Signal>({ key: 0 });

  const columns: ColumnsType<{ key: React.Key; name?: string }> = [
    {
      title: "名称",
      dataIndex: "name",
      width: "200px",
    },
    {
      title: "动作",
      dataIndex: "action",
      render: (_, record) => (
        <Popconfirm
          title="确认删除?"
          okText="确定"
          cancelText="取消"
          onConfirm={(e) => {
            e?.stopPropagation();
            deleteSignal(record.key);
          }}
        >
          <a>
            <DeleteOutlined />
          </a>
        </Popconfirm>
      ),
    },
  ];

  const initFile = () => {
    console.log("init");
  };
  const openFile = () => {
    console.log("open");
  };
  const saveFile = () => {
    console.log("save");
  };

  const appendSignal = (id: string) => {
    let config: ArgsProps = {
      message: "错误",
      placement: "topLeft",
      duration: 1,
    };
    if (/^[0-9A-Fa-f]+$/.test(id) === false) {
      return notification.open({
        ...config,
        description: "新消息的ID不正确, 期望输入16进制的数字.",
      });
    }
    const num = parseInt(id, 16);
    if (num <= 0) {
      return notification.open({
        ...config,
        description: "新消息的ID必须大于零.",
      });
    }
    const key = num.toString(16);
    let signal = listSignals.find((item) => {
      return item.key === key;
    });
    if (signal) {
      return notification.open({
        ...config,
        description: "新消息的ID和已有消息[" + signal.name + "]的ID重复.",
      });
    }
    signal = { key: key, name: "SG_" + key, length: 8, items: [] };
    setListSignals([...listSignals, signal]);
    setSelRowKey(key);
  };

  const deleteSignal = (key: React.Key) => {
    const index = listSignals.findIndex((item) => {
      return item.key === key;
    });
    if (listSignals.length > 1) {
      if (index === listSignals.length - 1) {
        setSelRowKey(listSignals[index - 1].key);
      } else {
        setSelRowKey(listSignals[index + 1].key);
      }
    } else {
      setSelRowKey(undefined);
    }
    setListSignals(
      listSignals.filter((item) => {
        return item.key !== key;
      })
    );
  };

  const modifySignal = (signal?: Signal) => {
    setIsModalOpen(false);
    if (typeof signal !== "undefined") {
      setListSignals(
        listSignals.map((item) => {
          if (item.key === signal.key) {
            let { items, ...others } = signal;
            return { ...item, ...others };
          } else {
            return item;
          }
        })
      );
    }
  };

  const selectRow = (key: React.Key) => {
    setSelRowKey(key);
  };

  return (
    <Layout>
      <Header>
        <Row>
          <Col span={8}>
            <Banner image={logo} title="DBC Editor" />
          </Col>
          <Col span={16}>
            <Space size="large" style={{ float: "right" }}>
              <Button type="primary" onClick={initFile}>
                <FileAddOutlined />
                新建文件
              </Button>
              <Button type="primary" onClick={openFile}>
                <FolderOpenOutlined />
                打开文件
              </Button>
              <Button type="primary" onClick={saveFile}>
                <SaveOutlined />
                保存文件
              </Button>
            </Space>
          </Col>
        </Row>
      </Header>
      <Layout>
        <Sider theme="light" width={320}>
          <div style={{ margin: "10px" }}>
            <Input.Group compact>
              <Input
                type="text"
                style={{ width: "170px" }}
                addonBefore="ID(16进制)"
                value={newRowKey}
                onChange={(e) => {
                  setNewRowKey(e.target.value);
                }}
                onPressEnter={() => {
                  appendSignal(newRowKey);
                }}
              />
              <Button
                type="primary"
                style={{ width: "130px" }}
                onClick={() => {
                  appendSignal(newRowKey);
                }}
              >
                <PlusOutlined />
                新增信号
              </Button>
            </Input.Group>
          </div>
          <Table
            rowSelection={{
              type: "radio",
              selectedRowKeys: selRowKey ? [selRowKey] : [],
              onChange: (keys: React.Key[]) => {
                selectRow(keys[0]);
              },
            }}
            columns={columns}
            dataSource={listSignals}
            showHeader={false}
            pagination={false}
            scroll={{ y: "540px" }}
            onRow={(record) => ({
              onClick: () => {
                selectRow(record.key);
              },
            })}
          />
        </Sider>
        <Content style={{ padding: "25px 50px" }}>
          {typeof selRowKey === "undefined" ? (
            <Table dataSource={[]} showHeader={false} />
          ) : (
            <>
              <Descriptions
                bordered={true}
                title="信号详情"
                extra={
                  <Button
                    type="primary"
                    onClick={() => {
                      setEditSignal(
                        listSignals.find((item) => {
                          return item.key === selRowKey;
                        }) || { key: 0 }
                      );
                      setIsModalOpen(true);
                    }}
                  >
                    编辑
                  </Button>
                }
              >
                <Descriptions.Item label="标识">
                  {
                    listSignals.find((item) => {
                      return item.key === selRowKey;
                    })?.key
                  }
                </Descriptions.Item>
                <Descriptions.Item label="名称">
                  {
                    listSignals.find((item) => {
                      return item.key === selRowKey;
                    })?.name
                  }
                </Descriptions.Item>
                <Descriptions.Item label="长度">
                  {
                    listSignals.find((item) => {
                      return item.key === selRowKey;
                    })?.length
                  }
                </Descriptions.Item>
                <Descriptions.Item label="备注">
                  {
                    listSignals.find((item) => {
                      return item.key === selRowKey;
                    })?.comment
                  }
                </Descriptions.Item>
              </Descriptions>
              <Modal
                title="编辑信号"
                okText="确定"
                cancelText="取消"
                open={isModalOpen}
                onOk={() => modifySignal(editSignal)}
                onCancel={() => setIsModalOpen(false)}
              >
                <Space direction="vertical" style={{ width: "100%" }}>
                  <Input
                    type="text"
                    addonBefore="名称"
                    value={editSignal.name}
                    onChange={(e) => {
                      setEditSignal({ ...editSignal, name: e.target.value });
                    }}
                  />
                  <Input
                    type="number"
                    addonBefore="长度"
                    value={editSignal.length}
                    onChange={(e) => {
                      setEditSignal({
                        ...editSignal,
                        length: parseInt(e.target.value),
                      });
                    }}
                  />
                  <Input
                    type="text"
                    addonBefore="备注"
                    value={editSignal?.comment}
                    onChange={(e) => {
                      setEditSignal({ ...editSignal, comment: e.target.value });
                    }}
                  />
                </Space>
              </Modal>
              <Divider>成员列表{selRowKey}</Divider>
            </>
          )}
        </Content>
      </Layout>
    </Layout>
  );
};

export default App;
